package com.power.project.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeUtil;
import com.power.base.service.impl.BaseServiceImpl;
import com.power.common.exception.CustomBizException;
import com.power.common.util.NanoidUtil;
import com.power.project.dao.Ww_departDao;
import com.power.project.dao.Ww_depart_userDao;
import com.power.project.interfaces.CustomNode;
import com.power.project.model.P_projectuser;
import com.power.project.model.Ww_depart;
import com.power.project.model.Ww_depart_user;
import com.power.project.model.Ww_user;
import com.power.project.model.bo.DepartLeaderSetBO;
import com.power.project.model.bo.DepartSaveuserBO;
import com.power.project.model.bo.DepartmentSaveBO;
import com.power.project.model.bo.DepartmentSortBO;
import com.power.project.model.dto.UserDepartDTO;
import com.power.project.model.vo.DepartLeaderForSetVO;
import com.power.project.model.vo.feignvo.Depart;
import com.power.project.service.Ww_departService;
import com.power.project.service.Ww_depart_userService;
import com.power.project.service.Ww_userService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 企业微信部门信息业务层实现
 */
@Service
public class Ww_departServiceImpl extends BaseServiceImpl implements Ww_departService {

    public static String DEPART_ROOT_PARENT_ID = "0";

    @Autowired
    private Ww_departDao dao;

    @Autowired
    private Ww_depart_userDao departUserDao;

    @Autowired
    private Ww_depart_userService depart_userService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void removeById(String departId) {
        dao.deleteByDepartId(departId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(DepartmentSaveBO saveBO) {
        List<Ww_depart> list = dao.findByParentidAndTenantid(saveBO.getParentId(), saveBO.getTenantId());

        if (list.stream().anyMatch(t -> t.getName().equals(saveBO.getName()))) {
            throw new CustomBizException("部门已存在");
        }

        if (StringUtils.isEmpty(saveBO.getParentId())) {
            saveBO.setParentId(DEPART_ROOT_PARENT_ID);
        }
        saveBO.setDepartId(NanoidUtil.randomTmNanoId());

        int sortNum;
        if (CollectionUtils.isEmpty(list)) {
            sortNum = 1;
        } else {
            sortNum = list.get(0).getSort_num() + 1;
        }
        dao.save(new Ww_depart(saveBO, sortNum));
    }

    @Override
    public List<Tree<String>> tree(String tenantId) {
        List<Ww_depart> list = dao.findByTenantidEquals(tenantId);

        List<Tree<String>> tree = TreeUtil.build(list, DEPART_ROOT_PARENT_ID, (depart, treeNode) -> {
            treeNode.setId(depart.getDepartid());
            treeNode.setParentId(depart.getParentid());
            treeNode.setWeight(depart.getSort_num());
            treeNode.setName(depart.getName());
            // 扩展属性 ...nodeType 0:部门 1:人员
            treeNode.putExtra("leaderIds", depart.getDepartment_leader());
//            treeNode.putExtra("nodeType", 0);
//            treeNode.putExtra("available", Boolean.TRUE);
//            treeNode.putExtra("selected", Boolean.FALSE);
        });
        return tree;
    }

    @Override
    public List<Tree<String>> departUserTree(String tenantId) {
        List<CustomNode> all = new ArrayList<>();

        List<Ww_depart> list = dao.findByTenantidEquals(tenantId);
        List<UserDepartDTO> allDepartUsers = departUserDao.getAllByTenantId(tenantId);

        all.addAll(list);
        all.addAll(allDepartUsers);

        List<Tree<String>> tree = TreeUtil.build(all, "0", (obj, treeNode) -> {
            treeNode.setId(obj.getNodeId());
            treeNode.setParentId(obj.getParentNodeId());
            treeNode.setWeight(obj.getNodeWeight());
            treeNode.setName(obj.getNodeName());
            // 扩展属性 ...nodeType 0:部门 1:人员
            treeNode.putExtra("type", obj.getType().getCode());
        });
        return tree;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void rename(DepartmentSaveBO saveBO) {
        Ww_depart depart = getByDepartId(saveBO.getDepartId());
        if (depart.getName().equals(saveBO.getName())) {
            return;
        }

        List<Ww_depart> list = dao.findByParentidAndTenantid(depart.getParentid(), depart.getTenantid());
        if (list.stream().anyMatch(t -> !t.getDepartid().equals(saveBO.getDepartId()) && saveBO.getName().equals(t.getName()))) {
            throw new CustomBizException("部门已存在");
        }

        depart.setName(saveBO.getName());
        dao.save(depart);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void sort(DepartmentSortBO sortBO) {
        Ww_depart parent = getByDepartId(sortBO.getParentId());
        Ww_depart current = getByDepartId(sortBO.getCurId());
        if (!parent.getTenantid().equals(current.getTenantid())) {
            throw new CustomBizException("不能跨租户移动部门");
        }

        List<Ww_depart> children = dao.findAllByDepartId(sortBO.getSortIds());
        Map<String, Ww_depart> map = children.stream().collect(Collectors.toMap(Ww_depart::getDepartid, Function.identity()));
        for (int i = 0; i < sortBO.getSortIds().size(); i++) {
            String id = sortBO.getSortIds().get(i);
            Ww_depart child = map.get(id);
            child.setSort_num(i + 1);
            child.setParentid(parent.getDepartid());
            child.setTenantid(parent.getTenantid());
        }

        dao.saveAll(children);
    }

    @Override
    public List<DepartLeaderForSetVO> leaderList(String departId) {
        Ww_depart depart = getByDepartId(departId);
        return dao.findByDepartIdAndTenantId(depart.getDepartid(), depart.getTenantid());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void setLeader(DepartLeaderSetBO setBO) {
        Ww_depart depart = getByDepartId(setBO.getDepartId());
        depart.setDepartment_leader(String.join(",", setBO.getUserIds()));
        dao.save(depart);

        departUserDao.updateNotLeader(depart.getDepartid(), depart.getTenantid());
        departUserDao.updateIsLeader(setBO.getUserIds(), depart.getDepartid(), depart.getTenantid());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveUsers(DepartSaveuserBO saveuserBO) {
        // 从 BO 中获取数据
        String departId = saveuserBO.getDepartId();
        List<String> userIds = saveuserBO.getUserIds();
        List<String> departmentLeaders = saveuserBO.getDepartment_leader();
        String tenantId = saveuserBO.getTenantid();

        // 检查部门是否存在
        Ww_depart depart = dao.getByDepartId(departId);
        if (depart == null){
            throw new CustomBizException("操作部门不存在");
        }

        //判断是否修改了负责人
        String leaderIdsBO = String.join(",", saveuserBO.getDepartment_leader());
        if (!leaderIdsBO.equals(depart.getDepartment_leader())) {
            depart.setDepartment_leader(leaderIdsBO);
            dao.updateleaderById(saveuserBO.getDepartId(), leaderIdsBO);
        }
        // 根据用户ID列表查找用户
        Set<String> leaderIds = new HashSet<>(departmentLeaders);
        List<Ww_user> users = depart_userService.findByUserId(userIds);

        // 创建 Ww_depart_user 对象列表
        List<Ww_depart_user> departUsers = users.stream()
                .map(user -> {
                    Ww_depart_user departUser = new Ww_depart_user();
                    departUser.setWwuserid(user.getUserid());
                    departUser.setDepartid(departId);
                    departUser.setTenantid(tenantId);
                    departUser.setIsleader(leaderIds.contains(user.getUserid()) ? 1 : 0);
                    return departUser;
                })
                .collect(Collectors.toList());
        // 保存部门用户关系
        depart_userService.saveAll(departUsers);
    }



    @Override
    public List<Ww_user> queryUsers(String departId) {
        return departUserDao.queryUsers(departId);
    }

    @Override
    public List<Ww_depart> getLeadDepartment(String userId, String tenantId) {
        return dao.getLeadDepartment(userId, tenantId);
    }

    @Override
    public void resetLeaders(List<String> departIds, String tenantId) {
        dao.resetLeaders(departIds, tenantId);
    }

    @Override
    public Ww_depart getByDepartId(String departId) {
        Ww_depart depart = dao.getByDepartId(departId);
        if (depart == null){
            throw new CustomBizException("操作部门不存在");
        }
        return depart;
    }

    @Override
    public List<Ww_depart> getByParentId(String parentId) {
        List<Ww_depart> list = dao.getByParentId(parentId);
        if (list == null){
            throw new CustomBizException("该部门下无子部门");
        }
        return list;
    }


    @Override
    public List<Depart> queryAllDepartWechat(String tenantId) {
        List<Ww_depart> list = dao.queryAllDepartWechat(tenantId);
        return list.stream().map(Depart::new).collect(Collectors.toList());
    }
}
